স্প্রিং জেডিবিসি (Spring JDBC) তে Exception Handling একটি গুরুত্বপূর্ণ বিষয়, কারণ ডেটাবেস অপারেশনগুলির সময় অনেক ধরনের ত্রুটি (Exception) ঘটতে পারে। যেমন SQL সিনট্যাক্স ত্রুটি, ডেটাবেস কনফিগারেশন ত্রুটি, সংযোগ ত্রুটি, বা ডেটাবেসে ডেটার অনুপস্থিতি। স্প্রিং জেডিবিসি একটি একটি ইউনিফাইড এক্সেপশন হ্যান্ডলিং মেকানিজম প্রদান করে, যা জাভার স্ট্যান্ডার্ড এক্সেপশন ক্লাসগুলির পরিবর্তে স্প্রিংয়ের নিজস্ব এক্সেপশন শ্রেণী ব্যবহার করে। এর ফলে, আপনি সহজেই বিভিন্ন ধরনের ত্রুটি পরিচালনা করতে পারেন এবং ডেটাবেস অপারেশনগুলো আরও নিরাপদ ও সহজে সম্পন্ন করতে পারেন।
স্প্রিং জেডিবিসি DataAccessException
শ্রেণী ব্যবহার করে সমস্ত JDBC সম্পর্কিত ত্রুটিগুলি পরিচালনা করে। এটি RuntimeException থেকে সম্প্রসারিত এবং স্প্রিং ডাটাবেসের সকল এক্সেপশন ক্লাসের মৌলিক শ্রেণী। এর মাধ্যমে, স্প্রিং অ্যাপ্লিকেশনগুলো JDBC এক্সেপশনগুলিকে সহজে হ্যান্ডেল করতে পারে।
স্প্রিং JDBC Exception Handling এর বিভিন্ন শ্রেণী (Classes):
DataAccessException
: এটি মূল এক্সেপশন ক্লাস, যা বিভিন্ন স্প্রিং ডাটাবেস এক্সেপশন শ্রেণীর সাধারণ শ্রেণী।DuplicateKeyException
: যখন আপনি একই কী দিয়ে একটি রেকর্ড ইনসার্ট করার চেষ্টা করেন।DataIntegrityViolationException
: যখন ডেটাবেসের মধ্যে ডেটা সঠিক না থাকে, যেমন অপর্যাপ্ত কলাম, নাল ভ্যালু ইত্যাদি।EmptyResultDataAccessException
: যখন কোনো ডেটা রিটার্ন না হয়।IncorrectResultSizeDataAccessException
: যখন একটি কুইরি অনেক বেশি বা কম রেকর্ড রিটার্ন করে।স্প্রিং এক্সেপশন হ্যান্ডলিং সাধারণভাবে কিছু সাধারণ এক্সেপশন ধরবে, এবং এর মাধ্যমে আপনার অ্যাপ্লিকেশন আরো স্থিতিস্থাপক হয়ে উঠবে।
ধরা যাক, আমরা একটি DAO ক্লাস তৈরি করেছি যা একটি কর্মী (Employee) টেবিল থেকে ডেটা রিট্রিভ করে এবং ইনসার্ট করে। আমরা এখানে Exception Handling দেখাবো।
এটি পূর্ববর্তী উদাহরণের মতোই থাকবে।
<dependencies>
<!-- Spring JDBC Dependency -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.20</version>
</dependency>
<!-- MySQL JDBC Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
</dependencies>
এখন, একটি DAO ক্লাস তৈরি করা হবে, যেখানে আমরা DataAccessException
ব্যবহার করে Exception Handling করব।
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public class EmployeeDao {
private JdbcTemplate jdbcTemplate;
// Setter method for JdbcTemplate
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// Insert an employee into the database using prepared statement
public void addEmployee(Employee employee) {
try {
String sql = "INSERT INTO employee (id, name, salary) VALUES (?, ?, ?)";
jdbcTemplate.update(sql, employee.getId(), employee.getName(), employee.getSalary());
} catch (DataAccessException e) {
// Handle SQL errors
System.out.println("Error inserting employee: " + e.getMessage());
}
}
// Fetch an employee by ID using JDBC Template
public Employee getEmployeeById(int id) {
Employee employee = null;
try {
String sql = "SELECT * FROM employee WHERE id = ?";
employee = jdbcTemplate.queryForObject(sql, new Object[]{id}, new EmployeeRowMapper());
} catch (DataAccessException e) {
// Handle case when no data is found or other errors
System.out.println("Error fetching employee: " + e.getMessage());
}
return employee;
}
}
class Employee {
private int id;
private String name;
private double salary;
// Getters and Setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
class EmployeeRowMapper implements RowMapper<Employee> {
@Override
public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
Employee employee = new Employee();
employee.setId(rs.getInt("id"));
employee.setName(rs.getString("name"));
employee.setSalary(rs.getDouble("salary"));
return employee;
}
}
এখন আমরা একটি মেইন ক্লাস তৈরি করব, যেখানে আমরা DataAccessException
হ্যান্ডলিং দেখব।
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloSpringJDBCExceptionHandling {
public static void main(String[] args) {
// Load the Spring context
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// Get the EmployeeDao bean
EmployeeDao employeeDao = (EmployeeDao) context.getBean("employeeDao");
// Create a new employee
Employee employee = new Employee();
employee.setId(1);
employee.setName("John Doe");
employee.setSalary(50000);
// Insert employee into the database
try {
employeeDao.addEmployee(employee);
} catch (Exception e) {
System.out.println("Error during insertion: " + e.getMessage());
}
// Fetch the employee by ID
try {
Employee fetchedEmployee = employeeDao.getEmployeeById(1);
if (fetchedEmployee != null) {
System.out.println("Employee: " + fetchedEmployee.getName() + ", Salary: " + fetchedEmployee.getSalary());
} else {
System.out.println("Employee not found");
}
} catch (Exception e) {
System.out.println("Error during fetching: " + e.getMessage());
}
}
}
আপনার MySQL ডেটাবেসে একটি employee
টেবিল তৈরি করুন:
CREATE TABLE employee (
id INT PRIMARY KEY,
name VARCHAR(50),
salary DECIMAL(10, 2)
);
DataAccessException
: এটি স্প্রিংয়ের সাধারণ এক্সেপশন ক্লাস। যখন কোন ডেটাবেস অপারেশন ত্রুটির সম্মুখীন হয়, এটি ব্যবহার করা হয়।DataAccessException
এর মধ্যে ধরা পড়ে।EmptyResultDataAccessException
অথবা DataAccessException
হতে পারে। queryForObject
মেথড ব্যবহার করলে, কোনো ডেটা না পাওয়া গেলে এটি EmptyResultDataAccessException
ছুঁড়ে দেয়।DuplicateKeyException
ছুঁড়ে দেয়া হবে।স্প্রিং জেডিবিসি (Spring JDBC) Exception Handling খুবই গুরুত্বপূর্ণ, কারণ এটি ডেটাবেসে ভুল, ত্রুটি বা ব্যতিক্রমগুলিকে সঠিকভাবে পরিচালনা করতে সহায়তা করে। স্প্রিংয়ের DataAccessException
শ্রেণীটি ব্যবহার করে আমরা ডেটাবেস এক্সেপশনগুলিকে সহজে ধরতে পারি এবং হ্যান্ডল করতে পারি, ফলে অ্যাপ্লিকেশন আরও স্থিতিস্থাপক হয়ে ওঠে।
স্প্রিং জেডিবিসি (Spring JDBC) ডেটাবেসের সাথে কাজ করার সময় ডেটাবেস অপারেশনগুলি অনেক ধরনের এক্সেপশন (Exception) সৃষ্টি করতে পারে, যেমন কনফিগারেশন সমস্যাগুলি, কুয়েরি সংশোধন, কানেকশন ব্যর্থতা, ডেটাবেস সংক্রান্ত সমস্যা ইত্যাদি। সাধারণভাবে, JDBC অ্যাপ্লিকেশনগুলিতে এক্সেপশন হ্যান্ডলিংকে বেশ জটিল হতে পারে, কারণ সেগুলির মধ্যে বিভিন্ন ধরনের এক্সেপশন থাকে। তবে স্প্রিং জেডিবিসি এক্সেপশন হ্যান্ডলিং কে সহজ এবং কার্যকর করে তোলে।
স্প্রিং জেডিবিসি এর মাধ্যমে এক্সেপশন হ্যান্ডলিং যথেষ্ট গুরুত্বপূর্ণ, কারণ এটি:
DataAccessException
হ্যান্ডলিং মেকানিজম ব্যবহার করে, যা একটি রানটাইম এক্সেপশন। এটি সমস্ত জেডিবিসি সম্পর্কিত এক্সেপশনগুলিকে কভার করে এবং ব্যবহারকারীকে কমপ্লেক্স JDBC এক্সেপশন হ্যান্ডলিং থেকে মুক্তি দেয়।SQLException
গুলো সাধারণত ডেটাবেস নির্ভর এক্সেপশন, যা প্রয়োগে কোনো সমস্যা হলে DataAccessException
এ রূপান্তরিত হয়।DataAccessException
এর মাধ্যমে সমস্ত এক্সেপশনকে র্যাপ (wrap) করে দেয়। এর মধ্যে বিভিন্ন সুনির্দিষ্ট এক্সেপশন ক্লাস যেমন DuplicateKeyException
, DataIntegrityViolationException
, CannotAcquireLockException
ইত্যাদি অন্তর্ভুক্ত রয়েছে।SQLException
, SQLWarning
, SQLFeatureNotSupportedException
) থাকতে পারে। স্প্রিং JDBC এ DataAccessException
ব্যবহার করে, এগুলিকে একটি সাধারণ এক্সেপশন কাঠামোতে আনা হয়, যা এক্সেপশন হ্যান্ডলিংকে অনেক সহজ করে তোলে।import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
public class EmployeeDao {
private JdbcTemplate jdbcTemplate;
// DataSource Inject করা হচ্ছে
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
// ইনসার্ট অপারেশন: এক্সেপশন হ্যান্ডলিং সহ
public void insertEmployee(Employee employee) {
String sql = "INSERT INTO employee (id, name, age) VALUES (?, ?, ?)";
try {
jdbcTemplate.update(sql, employee.getId(), employee.getName(), employee.getAge());
} catch (DataAccessException e) {
// এক্সেপশন হ্যান্ডলিং
System.out.println("Error while inserting employee: " + e.getMessage());
// লগিং করা বা কাস্টম এক্সেপশন তৈরি করা হতে পারে
}
}
// ডেটাবেস থেকে ডেটা পড়া: এক্সেপশন হ্যান্ডলিং সহ
public Employee getEmployeeById(int id) {
String sql = "SELECT * FROM employee WHERE id = ?";
try {
return jdbcTemplate.queryForObject(sql, new Object[] {id}, new EmployeeRowMapper());
} catch (DataAccessException e) {
// এক্সেপশন হ্যান্ডলিং
System.out.println("Error while fetching employee: " + e.getMessage());
return null; // বা কাস্টম এক্সেপশন
}
}
}
এখানে, DataAccessException
কাস্টম এক্সেপশন হিসেবে ব্যবহৃত হচ্ছে। এর মধ্যে একাধিক ধরনের ব্যতিক্রমী পরিস্থিতি ধরা পড়তে পারে যেমন SQL সমস্যা, ডেটাবেস সংযোগ সমস্যা, বা ডেটা ইনটেগ্রিটি সমস্যা।
স্প্রিং জেডিবিসি আপনাকে কাস্টম এক্সেপশন হ্যান্ডলিংয়ের মাধ্যমে ডেটাবেস এক্সেপশনগুলিকে যথাযথভাবে প্রক্রিয়া করতে সহায়তা করে। এক্সেপশনটি ধরা এবং এর সঠিক ব্যাখ্যা প্রদান করা অ্যাপ্লিকেশন ডেভেলপমেন্টে গুরুত্বপূর্ণ।
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
public class EmployeeDao {
public void insertEmployee(Employee employee) {
String sql = "INSERT INTO employee (id, name, age) VALUES (?, ?, ?)";
try {
jdbcTemplate.update(sql, employee.getId(), employee.getName(), employee.getAge());
} catch (DuplicateKeyException e) {
// ডুপ্লিকেট কী ত্রুটি
System.out.println("Duplicate key error: " + e.getMessage());
} catch (DataAccessException e) {
// সাধারণ ডেটাবেস এক্সেপশন
System.out.println("Database error: " + e.getMessage());
} catch (Exception e) {
// অন্যান্য সাধারণ এক্সেপশন
System.out.println("Unexpected error: " + e.getMessage());
}
}
}
এখানে DuplicateKeyException
এবং সাধারণ DataAccessException
এর মাধ্যমে পৃথক পৃথক এক্সেপশন ধরা হয়েছে এবং সেগুলি প্রক্রিয়া করা হয়েছে।
DataAccessException
এর মাধ্যমে সমস্ত ধরনের এক্সেপশনকে কভার করে, যা ডেটাবেস সম্পর্কিত সমস্ত ত্রুটি ব্যবস্থাপনা সহজ করে।DuplicateKeyException
, DataIntegrityViolationException
) নির্দিষ্টভাবে চিহ্নিত করে, যা ডেভেলপারদের উপযুক্ত ব্যবস্থা গ্রহণ করতে সহায়তা করে।স্প্রিং জেডিবিসি তে এক্সেপশন হ্যান্ডলিং অত্যন্ত গুরুত্বপূর্ণ, কারণ এটি ডেটাবেস অপারেশনের নির্ভরযোগ্যতা এবং স্থিরতা বজায় রাখে। DataAccessException
এর মাধ্যমে এক্সেপশনগুলিকে সঠিকভাবে র্যাপ করা এবং কাস্টম এক্সেপশন তৈরি করা অ্যাপ্লিকেশনকে আরও নিরাপদ এবং ব্যবহারকারী বান্ধব করে তোলে।
SQLExceptionTranslator
এবং DataAccessException
স্প্রিং জেডিবিসি (Spring JDBC) এর দুটি গুরুত্বপূর্ণ উপাদান, যা ডেটাবেস অপারেশনের সময় ঘটে যাওয়া এক্সসেপশনগুলোকে হ্যান্ডল করতে সাহায্য করে। স্প্রিং এর এই মেকানিজমগুলি জেডিবিসি (JDBC) এর প্রচলিত SQLException
এর বদলে একটি ইউনিফাইড এক্সসেপশন হ্যান্ডলিং পদ্ধতি সরবরাহ করে।
স্প্রিং SQLExceptionTranslator
একটি ইন্টারফেস যা SQLException
কে স্প্রিং-সুবিধাজনক DataAccessException
এ রূপান্তরিত করে। স্প্রিং এর JdbcTemplate
এবং অন্যান্য জেডিবিসি ক্লাসে এই ট্রান্সলেটরটি ডিফল্টভাবে ব্যবহৃত হয়, যাতে ডেটাবেস এক্সসেপশনগুলিকে সহজ এবং পরিষ্কারভাবে হ্যান্ডল করা যায়।
যেহেতু SQLException
ডেটাবেসের জন্য বিশেষভাবে নির্দিষ্ট, এবং এর আচরণ বিভিন্ন ডেটাবেস ভেন্ডরের মধ্যে পরিবর্তিত হতে পারে, তাই স্প্রিং এই SQLException
-কে একটি সাধারণ এক্সসেপশনে রূপান্তর করে যার মাধ্যমে স্প্রিং অ্যাপ্লিকেশনটি ডেটাবেস সম্পর্কিত সমস্যা সমাধানে আরও সহজ হয়।
SQLExceptionTranslator
এর কাজ:
SQLException
কে একটি ইউনিফাইড DataAccessException
এ রূপান্তরিত করে, যা স্প্রিং জেডিবিসি এর সাধারণ এক্সসেপশন ক্লাস।DataIntegrityViolationException
, DuplicateKeyException
, BadSqlGrammarException
ইত্যাদি, যা অধিক নির্দিষ্ট এবং সঠিকভাবে হ্যান্ডল করা যায়।DataAccessException
একটি রানটাইম এক্সসেপশন যা স্প্রিং জেডিবিসি এবং স্প্রিং ডেটা অ্যাক্সেসের সমস্ত এক্সসেপশনকে সাধারণভাবে প্রতিনিধিত্ব করে। এটি একটি আবস্ট্রাক্ট ক্লাস যা JdbcTemplate
, NamedParameterJdbcTemplate
, SimpleJdbcTemplate
ইত্যাদি ক্লাসের মাধ্যমে ডেটাবেস অপারেশনগুলি চালানোর সময় ঘটতে থাকা এক্সসেপশনগুলোকে ধরা ও হ্যান্ডল করার জন্য ব্যবহৃত হয়।
স্প্রিং ডেটাবেস এক্সসেপশনের সাথে কাজ করার প্রধান সুবিধা হলো, SQLException
কে স্প্রিং এর অভ্যন্তরীণ এক্সসেপশন হ্যান্ডলিং মেকানিজমের মাধ্যমে রূপান্তর করা হয়, ফলে ডেটাবেসের ড্রাইভার এবং স্প্রিং ফ্রেমওয়ার্কের মধ্যে সঙ্গতি রক্ষা করা হয়।
SQLExceptionTranslator
এবং DataAccessException
ব্যবহার করা হয়?SQLExceptionTranslator
এবং DataAccessException
ব্যবহার করার মাধ্যমে স্প্রিং এক্সসেপশন হ্যান্ডলিং অনেক সহজ ও একক রূপে হয়ে থাকে, যা বিভিন্ন ধরনের ডেটাবেস এক্সসেপশনকে সাধারণভাবে ট্রিট করতে সাহায্য করে।DuplicateKeyException
, BadSqlGrammarException
, DataIntegrityViolationException
ইত্যাদি। এর ফলে ডেটাবেসের সমস্যা আরও পরিষ্কারভাবে চিহ্নিত করা যায়।SQLException
ব্যবহারের পরিবর্তে DataAccessException
ব্যবহার করা কোডকে ক্লিন এবং রক্ষণাবেক্ষণযোগ্য করে তোলে।ধরা যাক, আমরা একটি সাধারণ স্প্রিং জেডিবিসি অ্যাপ্লিকেশন তৈরি করেছি, যেখানে ডেটাবেসের একটি টেবিল থেকে ডেটা বের করা হচ্ছে এবং যদি কোনো ভুল হয়, তখন তা হ্যান্ডল করার জন্য DataAccessException
ব্যবহার করা হয়।
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SQLExceptionTranslator;
public class EmployeeDao {
private JdbcTemplate jdbcTemplate;
public EmployeeDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void getEmployeeById(int id) {
String sql = "SELECT * FROM Employee WHERE id = ?";
try {
jdbcTemplate.queryForObject(sql, new Object[]{id}, new EmployeeRowMapper());
} catch (DataAccessException e) {
SQLExceptionTranslator sqlExceptionTranslator = jdbcTemplate.getExceptionTranslator();
// SQLExceptionকে DataAccessException এ রূপান্তর করা
System.out.println("Error occurred: " + sqlExceptionTranslator.translate("select", sql, e));
}
}
}
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
public class EmployeeDao {
private JdbcTemplate jdbcTemplate;
public EmployeeDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void deleteEmployee(int id) {
String sql = "DELETE FROM Employee WHERE id = ?";
try {
jdbcTemplate.update(sql, id);
} catch (DataAccessException e) {
System.out.println("An error occurred during deletion: " + e.getMessage());
}
}
}
SQLException
কে একটি DataAccessException
এ রূপান্তরিত করে, যাতে স্প্রিং জেডিবিসির সঙ্গে এক্সসেপশন হ্যান্ডলিং সহজ হয়।SQLException
-কে সাধারণ এবং স্পষ্ট এক্সসেপশনগুলিতে রূপান্তরিত করা সম্ভব, যা কোডকে ক্লিন, পাঠযোগ্য এবং রক্ষণাবেক্ষণযোগ্য করে তোলে।Spring JDBC-এ Custom Exception তৈরি এবং সেগুলি সঠিকভাবে Handle করা গুরুত্বপূর্ণ, কারণ এটি আপনার অ্যাপ্লিকেশনকে আরও robust এবং মেইন্টেনেবল করে তোলে। Spring JDBC সাধারণত SQLException অথবা DataAccessException (Spring JDBC এর এক্সসেপশন হায়ারার্কি) ব্যবহার করে, তবে আপনি যদি আরও নির্দিষ্ট এবং কাস্টমাইজড এক্সসেপশন তৈরি করতে চান, তবে সেটা আপনার কোডের কার্যকারিতা এবং ত্রুটি হ্যান্ডলিংকে আরো ভালো করতে সাহায্য করবে।
Spring-এ কাস্টম এক্সসেপশন তৈরি করতে, সাধারণত আপনি একটি নতুন ক্লাস তৈরি করবেন যা RuntimeException
অথবা Exception
ক্লাস থেকে ইনহেরিট করবে।
// Custom Exception class
public class UserNotFoundException extends RuntimeException {
// Default constructor
public UserNotFoundException(String message) {
super(message);
}
// Constructor with cause
public UserNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
এখানে:
UserNotFoundException
একটি কাস্টম এক্সসেপশন ক্লাস তৈরি করা হয়েছে যা RuntimeException
থেকে ইনহেরিট করেছে।super(message)
ব্যবহার করে আপনি এক্সসেপশন বার্তা পাঠাতে পারেন।এখন, ধরুন আমরা একটি রেপোজিটরি ক্লাস তৈরি করতে যাচ্ছি যেখানে ডেটাবেস থেকে ইউজারের তথ্য নেওয়ার সময় যদি কোনো ইউজার পাওয়া না যায়, তাহলে আমরা কাস্টম এক্সসেপশনটি থ্রো করবো।
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.Map;
@Repository
public class UserRepository {
@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
// Method to fetch user by ID
public User getUserById(int userId) {
String sql = "SELECT * FROM users WHERE user_id = :userId";
Map<String, Object> params = new HashMap<>();
params.put("userId", userId);
// Executing the query
User user = namedParameterJdbcTemplate.queryForObject(sql, params, new UserRowMapper());
// If user is not found, throw custom exception
if (user == null) {
throw new UserNotFoundException("User with ID " + userId + " not found.");
}
return user;
}
}
এখানে:
getUserById()
মেথডে যদি কোনো ইউজার না পাওয়া যায়, তাহলে আমরা UserNotFoundException
থ্রো করছি।queryForObject()
মেথডটি ইউজারকে ডেটাবেস থেকে ফেরত আনে, এবং যদি ইউজার না পাওয়া যায়, তাহলে user == null
চেকের মাধ্যমে কাস্টম এক্সসেপশন থ্রো করা হয়।Spring Framework এর @ControllerAdvice বা @ExceptionHandler ব্যবহার করে কাস্টম এক্সসেপশনগুলি গ্লোবালি হ্যান্ডল করা যেতে পারে। এটি একটি সাধারণ পদ্ধতি যেখানে আপনি এক্সসেপশন গুলোকে একটি সেন্ট্রাল প্লেসে ক্যাচ এবং হ্যান্ডল করতে পারেন।
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice;
@ControllerAdvice
public class GlobalExceptionHandler {
// Handle UserNotFoundException globally
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleUserNotFoundException(UserNotFoundException ex) {
// You can log the exception or send a custom response
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
// Handle any other general exceptions
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGeneralException(Exception ex) {
return new ResponseEntity<>("An unexpected error occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
এখানে:
ResponseEntity
ব্যবহার করা হয়েছে, যা HTTP স্ট্যাটাস এবং কাস্টম মেসেজ সহ রেসপন্স ফেরত দেয়।RuntimeException
বা Exception
ক্লাস থেকে ইনহেরিট করা হয়।@ControllerAdvice
বা @ExceptionHandler
ব্যবহার করে কাস্টম এক্সসেপশনগুলি গ্লোবালি হ্যান্ডল করা যেতে পারে। এটি আপনার অ্যাপ্লিকেশনের রেজিলিয়েন্স এবং রক্ষণাবেক্ষণ ক্ষমতা বৃদ্ধি করে।এভাবে Spring JDBC-তে Custom Exception তৈরি এবং Handle করা খুবই সহজ এবং কার্যকর পদ্ধতি।
Spring JDBC তে Exception Handling গুরুত্বপূর্ণ, কারণ ডেটাবেস অপারেশন চলাকালে যেকোনো ধরনের ব্যতিক্রম (Exception) ঘটতে পারে যেমন SQLException
, DataAccessException
ইত্যাদি। Spring JDBC এই ব্যতিক্রমগুলি সহজে পরিচালনা করার জন্য একটি DataAccessException শ্রেণী প্রদান করে, যা RuntimeException
এর একটি সাবক্লাস। এটি ডেটাবেস সংক্রান্ত ব্যতিক্রমগুলি আরও সরল এবং পরিষ্কারভাবে পরিচালনা করতে সাহায্য করে।
Spring JDBC ব্যতিক্রম ব্যবস্থাপনা (Exception Handling) এমনভাবে ডিজাইন করা হয়েছে যাতে ডেভেলপাররা ডেটাবেসের সঙ্গে কাজ করার সময় ব্যতিক্রমগুলি বুঝতে এবং মোকাবিলা করতে সহজে পারে। Spring বিভিন্ন ধরনের ব্যতিক্রম ফেলে, যেমন:
RuntimeException
এর সাবক্লাস এবং সমস্ত JDBC ব্যতিক্রমগুলির জন্য একটি সাধারণ শ্রেণী।DataAccessException
এর অধীনে থাকে এবং সাধারণ SQL সম্পর্কিত ত্রুটি রেপ্রেজেন্ট করে।Spring JDBC-তে ব্যতিক্রম পরিচালনা করার জন্য try-catch
ব্লক ব্যবহার করা হয়, তবে DataAccessException
সাধারণত ডিরেক্টলি ক্যাচ করা হয় না, কারণ Spring তা স্বয়ংক্রিয়ভাবে রূপান্তর করে থাকে।
ধরা যাক, আমাদের একটি Employee
টেবিল আছে এবং আমরা কিছু ডেটাবেস অপারেশন করব। যদি কোনো ত্রুটি ঘটে, তবে আমরা সেই ত্রুটির ব্যতিক্রমটি ধরা এবং প্রক্রিয়া করব।
প্রথমে, আপনাকে Spring JDBC এর জন্য ডিপেনডেন্সি যুক্ত করতে হবে।
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.24</version> <!-- সর্বশেষ সংস্করণ নিশ্চিত করতে Maven Repository থেকে চেক করুন -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.24</version>
</dependency>
HikariCP বা Tomcat Connection Pool ব্যবহার করে DataSource কনফিগারেশন করতে হবে।
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/your_database");
hikariConfig.setUsername("your_username");
hikariConfig.setPassword("your_password");
hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
return new HikariDataSource(hikariConfig);
}
}
JdbcTemplate
ব্যবহার:এখন, আমরা JdbcTemplate
এর মাধ্যমে ডেটাবেস অপারেশন করব এবং যদি কোনো ব্যতিক্রম ঘটে, আমরা তা try-catch ব্লকের মাধ্যমে ধরি।
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class EmployeeDAO {
private final JdbcTemplate jdbcTemplate;
@Autowired
public EmployeeDAO(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
// Employee ইনসার্ট করার জন্য
public void addEmployee(int id, String name, double salary) {
String sql = "INSERT INTO Employee (id, name, salary) VALUES (?, ?, ?)";
try {
jdbcTemplate.update(sql, id, name, salary);
System.out.println("Employee added successfully");
} catch (DataAccessException e) {
// SQLException বা অন্য ব্যতিক্রম DataAccessException এ রূপান্তরিত হবে
System.err.println("Error occurred while inserting employee: " + e.getMessage());
// আরও স্পেসিফিক ব্যতিক্রম প্রক্রিয়া করা যেতে পারে
}
}
// Employee পড়ার জন্য
public void getEmployeeById(int id) {
String sql = "SELECT * FROM Employee WHERE id = ?";
try {
Employee employee = jdbcTemplate.queryForObject(sql, new Object[]{id}, new EmployeeRowMapper());
System.out.println("Employee: " + employee.getName());
} catch (DataAccessException e) {
System.err.println("Error occurred while fetching employee: " + e.getMessage());
}
}
}
এখানে EmployeeRowMapper
ক্লাসটি ব্যবহার করা হয়েছে যা SQL রেজাল্ট সেট থেকে Employee
অবজেক্ট তৈরি করবে।
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public class EmployeeRowMapper implements RowMapper<Employee> {
@Override
public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
Employee employee = new Employee();
employee.setId(rs.getInt("id"));
employee.setName(rs.getString("name"));
employee.setSalary(rs.getDouble("salary"));
return employee;
}
}
এখন, আমরা EmployeeDAO
ক্লাসটি ব্যবহার করে ডেটাবেস অপারেশন করব এবং ব্যতিক্রম হ্যান্ডলিং করব।
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
// Spring কনটেক্সট ইনিশিয়ালাইজ করা
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DataSourceConfig.class);
EmployeeDAO employeeDAO = context.getBean(EmployeeDAO.class);
// Employee ইনসার্ট করা
employeeDAO.addEmployee(1, "John Doe", 50000);
// Employee পড়া
employeeDAO.getEmployeeById(1);
context.close();
}
}
DataAccessException
এ রূপান্তরিত হয়। এটি সাধারণত SQLException
থেকে রূপান্তরিত হয়।DataAccessException
এ রূপান্তরিত হয়ে যায়, তবে আপনি যদি চাচ্ছেন, আপনি এটি ক্যাচ করতে পারেন।SQLIntegrityConstraintViolationException
ক্যাচ করা হতে পারে যদি আপনি ডুপ্লিকেট কনস্ট্রেইন্ট লঙ্ঘন করেন (যেমন UNIQUE
constraint)।DataAccessException
এর মাধ্যমে করা হয়।Read more